import java.util.EmptyStackException;
import java.util.Stack;
import java.util.StringTokenizer;

public class MyDC extends calcArithmatic{

    private Stack<String> stack;

    public MyDC(){
        stack = new Stack<>();
    }

    public String calculate(String expr)throws ExprFormatException{
        String op1,op2;
        String result ="";
        String token;
        StringTokenizer tokenizer = new StringTokenizer(expr);
        while (tokenizer.hasMoreTokens()){
            token=tokenizer.nextToken();
            if(isOperator(token)){
                try{
                    op2=stack.pop();
                    op1=stack.pop();
                } catch (EmptyStackException e){
                    throw new ExprFormatException("Expression Format Error");
                }

                if (isOperator(op1) || isOperator(op2)) {
                    throw new ExprFormatException("Expression Format Error");
                }
                result=calcSingle(op1,op2,token);
                stack.push(result);
            } else {
                stack.push(token);
            }
        }
        result=stack.pop();
        if (!stack.empty()){
            throw new ExprFormatException("Expression Format Error");
        }
        return result;
    }

    public static int gcd(int x, int y){
        int temp;
        if (x<0){
            x*=-1;
        }
        if (y<0){
            y*=-1;
        }
        if (x<y) {
            temp = x;
            x = y;
            y = temp;
        }
        while (y!=0){
            temp=x%y;
            x=y;
            y=temp;
        }
        return x;
    }

    String calcSingle(String op1, String op2, String operation){
        String result = "";
        int dominator1=1,numerator1;//0/1
        int dominator2=1, numerator2;
        int dominator=1,numerator=0;
        if (op1.matches(".*/.*")){
            dominator1=Integer.valueOf(op1.split("/")[1]);
            numerator1=Integer.valueOf(op1.split("/")[0]);
        } else {
            numerator1=Integer.valueOf(op1);
        }
        if (op2.matches(".*/.*")){
            dominator2=Integer.valueOf(op2.split("/")[1]);
            numerator2=Integer.valueOf(op2.split("/")[0]);
        } else {
            numerator2=Integer.valueOf(op2);
        }
        switch (operation){
            case "+":
                numerator=numerator1*dominator2+numerator2*dominator1;
                dominator=dominator1*dominator2;
                break;
            case "-":
                numerator=numerator1*dominator2-numerator2*dominator1;
                dominator=dominator1*dominator2;
                break;
            case "*":
                numerator=numerator1*numerator2;
                dominator=dominator1*dominator2;
                break;
            case "÷":
                numerator=numerator1*dominator2;
                dominator=numerator2*dominator1;
                break;
            default:
        }
        if(0==dominator){
            throw new ArithmeticException();
        }
        int gcdivisor = gcd(numerator,dominator);
        if (dominator/gcdivisor!=1) {
            if (dominator<0){
                dominator*=-1;
                numerator*=-1;
            }
            result = result + numerator / gcdivisor + '/' + dominator / gcdivisor;
        }
        else {
            result = result + numerator / gcdivisor;
        }
        return result;
    }
}